#################################################################
# Programa que efetua o filtro da Base de Dados					#
# 																#
# Autora: Cristina Teixeira de Oliveira							#
# e-mail: cto@icmc.usp.br										#
#################################################################
 
#################################################################
# Ao chamar a função, devem ser passados um arquivo de a ser	#
# filtrado 	e a Base de Dados									#
# Ex.: filtraBaseDados entrada baseDados 						#
# Onde, entrada irá conter o a estrutura secundaria do RNAnc a 	#
# ser procurado na base.										#
################################################################# 
 
#!usr/bin/perl -w
use strict;

my $descBase;
my $estruturaBase;
my $sequenciaBase;
my $qtdeSubcadeiasBase;
my @subcadeiaBase;
my $qtdePareadosBase;
my $qtdeNaoPareadosBase;
my $totalAninhadosBase;

my $estruturaIn;
my $qtdeSubcadeiasIn;
my @subcadeiaIn;
my $qtdePareadosIn;
my $qtdeNaoPareadosIn;
my $totalAninhadosIn;

my $i;
my $linha; 
my $homologo;

#Definindo erro para corte de sequencias
my $erro=1.0;
my $intervalo;
my $LIqtdeSubcadeias;
my $LSqtdeSubcadeias;
my $LIqtdePareados;
my $LSqtdePareados;	
my $LIqtdeNaoPareado;
my $LSqtdeNaoPareado;
my $LItotalAninhados;
my $LStotalAninhados;		

# Exemplo de sequencias
# GTCCGCTCCGTCTATCAATACCGTTCGATTCGCTACCTTCGATGATTTTCGTACAGTCTG	........................((((..........))))..................	1	((((..........))))	4	42
# CCACTAGGAAGGCCTCAGTACGCCATGTCAGTTCTCCCCCGCGGATTTAGCTCAGTTGGG	..........(((........)))............(((.((.((......)).)).)))	2	(((........)))	(((.((.((......)).)).)))	10	22

sub extraiInformacao {	
	$linha = $_[0];
	#print "\nLinha: ", $linha;
	
	#Estrutura Secundaria
	$linha =~ s/(^[\.\(\)]*)//;
	#print "\nEstrutura Secundária: ", $1;
	$estruturaBase = $1;	
	$linha =~ s/(^\t)//;
	
	#Quantidade de Subcadeias
	$linha =~ s/(^[0-9]*)//;
	#print " Qtde Subcadeia: ", $1;
	$qtdeSubcadeiasBase = $1;
	$linha =~ s/(^\t)//;
	
	#Subcadeias		
	for ($i = 1;$i <= $qtdeSubcadeiasBase; $i=$i+1) {
    	$linha =~ s/(^[\.\(\)]*)//;
		#print " Subcadeia: ", $1;
		@subcadeiaBase[$i] = $1;
		
		$linha =~ s/(^\t)//;
	}
	
	#Quantidade de Pareamentos	
	$linha =~ s/(^[0-9]*)//;
	#print " Qtde Pareados: ", $1;
	$qtdePareadosBase = $1;
	$linha =~ s/(^\t)//;
	
	#Quantidade de Não-Pareados
	$linha =~ s/(^[0-9]*)//;
	#print " Qtde Não Pareado: ", $1;
	$qtdeNaoPareadosBase = $1;
	$linha =~ s/(^\t)//;
	
	#Quantidade de Não-Pareados
	$linha =~ s/(^[0-9]*)//;
	#print " Qtde Não Pareado: ", $1;
	$totalAninhadosBase = $1;
	$linha =~ s/(^\t)//;
	
}


if ($#ARGV < 2) {
 print "Erro na passagem do parametro\n";
 exit;
}

#$arquivo = $ARGV[0];
open(ARQ_Entrada, "<$ARGV[0]") || die "Arquivo não encontrado\n";

foreach $linha (<ARQ_Entrada>) {	
	&extraiInformacao($linha);
	$estruturaIn = $estruturaBase;
	$qtdeSubcadeiasIn = $qtdeSubcadeiasBase;
	@subcadeiaIn = @subcadeiaBase;
	$qtdePareadosIn = $qtdePareadosBase;
	$qtdeNaoPareadosIn = $qtdeNaoPareadosBase;
	$totalAninhadosIn = $totalAninhadosBase;		
}
close(ARQ_Entrada);

#$arquivo = $ARGV[1];
open(ARQ_BD, "<$ARGV[1]") || die "Arquivo da Base não encontrado\n";
#Arquivo para escrita do que sera buscado pelo Infernal
open(ARQ_BD_Filtrada, ">$ARGV[2]") || die "Arquivo para gerar Base não encontrado\n";

#Arquivo para gravar os descartados
my $Descartada = $ARGV[2];
$Descartada =~ s/Filtrada//;
$Descartada = $Descartada."Descartada"; 
open(ARQ_BD_Descartada, ">$Descartada") || die "Arquivo para gerar Base não encontrado\n";


#Calculando intervalo permitido da qtdeSubcadeias$linha =~ s/(^\t)//;
$intervalo = ($qtdeSubcadeiasIn*$erro);
$LIqtdeSubcadeias = int($qtdeSubcadeiasIn - $intervalo);
$LSqtdeSubcadeias = int($qtdeSubcadeiasIn + $intervalo + 0.5);
print "\nIntervalo: ", $intervalo, " qtdesubcadeia: ", $qtdeSubcadeiasIn, " Multiplicação: ", ($qtdeSubcadeiasIn*$erro);
print "\nqtdeSubcadeiasBase LI: ", $LIqtdeSubcadeias, "  LS: ", $LSqtdeSubcadeias;

$intervalo = ($qtdePareadosIn*$erro);
$LIqtdePareados = int($qtdePareadosIn - $intervalo);
$LSqtdePareados = int($qtdePareadosIn + $intervalo + 0.5);	
print "\nqtdePareadosBase LI: ", $LIqtdePareados, " LS: ", $LSqtdePareados;

$intervalo = ($qtdeNaoPareadosIn*$erro);
$LIqtdeNaoPareado = int($qtdeNaoPareadosIn - $intervalo);
$LSqtdeNaoPareado = int($qtdeNaoPareadosIn + $intervalo + 0.5);	
print "\nqtdeNaoPareadosBase LI: ", $LIqtdeNaoPareado, " LS: ", $LSqtdeNaoPareado;

$intervalo = ($totalAninhadosIn*$erro);
$LItotalAninhados = int($totalAninhadosIn - $intervalo);
$LStotalAninhados = int($totalAninhadosIn + $intervalo + 0.5);	
print "\ntotalAninhadosBase LI: ", $LItotalAninhados, " LS: ", $LStotalAninhados;

foreach $linha (<ARQ_BD>) {
	print "\nLinha: ", $linha;
	
	#Setando flag de semelhança do RNA
	$homologo = 1;
	
	#Descrição
	$linha =~ s/(^>[\w|\s]*\.)//;
	#print "\nDescrição: ", $1;
	$descBase = $1;	
	$linha =~ s/(^\t)//;
	
	#Sequencia
	$linha =~ s/(^[A-Z]*)//;
	#print " Sequencia: ", $1;
	$sequenciaBase = $1;	
	$linha =~ s/(^\t)//;
	
	&extraiInformacao($linha);
	
	#Efetuar comparação entre a entrada e a sequência atual
	
	#Comparando Quantidade de subcadeias encontradas
	#Se estiver fora do intervalo permitido não será colocado na Base filtrada		
#	if (($qtdeSubcadeiasBase < $LIqtdeSubcadeias)||($qtdeSubcadeiasBase > $LSqtdeSubcadeias)) {$homologo = 0; print "\nPAROU FILTR0 1";}
	#Caso esteja denrtro do limite anterior de quantidade de subcadeias irá comparar quantidade de bases Pareadas
	#Se estiver fora do intervalo permitido não será colocado na Base filtrada
#	else {		
#		if (($qtdePareadosBase < $LIqtdePareados)||($qtdePareadosBase > $LSqtdePareados)) {$homologo = 0; print "PAROU FILTRO 2";}
		#Caso esteja denrtro do limite anterior de quantidade de subcadeias irá comparar quantidade de bases Pareadas
		#Se estiver fora do intervalo permitido não será colocado na Base filtrada
#		else{
#			if (($qtdeNaoPareadosBase < $LIqtdeNaoPareado)||($qtdeNaoPareadosBase > $LSqtdeNaoPareado)) {$homologo = 0; print "PAROU FILTRO 3";}
			#Caso esteja denrtro do limite anterior de quantidade de bases Pareadas irá comparar a quantidade total de aninhamentos
			#Se estiver fora do intervalo permitido não será colocado na Base filtrada
#			else{
				if (($totalAninhadosBase < $LItotalAninhados)||($totalAninhadosBase > $LStotalAninhados)) {$homologo = 0; print "PAROU FILTRO 3";}
				#No caso abaixo sequencia passou pelos três filtros acima
				#Caso o RNA tenha características semelhantes com o RNA de entrada ele é escrito na Base já filtrada
				else {print ARQ_BD_Filtrada "$descBase\n$sequenciaBase\n";}
#			}						
#		}
#	}	
	if ($homologo == 0) {print ARQ_BD_Descartada "$descBase\n$sequenciaBase\n"};
}

close(ARQ_BD);
close(ARQ_BD_Filtrada);
close(ARQ_BD_Descartada);
    